package com.ruoyi.common.sms;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.tencentcloudapi.common.AbstractModel;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 腾讯云短信工具类
 * @author Ten
 */
@Slf4j
public class SendSmsUtil {

    private static final String SDK_APP_ID = "1401043388";

    /**
     * SecretId:AKIDDUsfP6hDdyEOQGvXxCSZWHKG2lLk1CE5
     * SecretKey:iEYzNcfbN8iLrERXTQK4d1HUaVIxRkvG
     * @param sendSmsEnum
     * @param phoneNumberSet1
     */
    private static final String TENCENTCLOUD_SECRET_ID = "AKIDDUsfP6hDdyEOQGvXxCSZWHKG2lLk1CE5";
    private static final String TENCENTCLOUD_SECRET_KEY = "iEYzNcfbN8iLrERXTQK4d1HUaVIxRkvG";

    public static void sendSms(SendSmsEnum sendSmsEnum, String... phoneNumberSet1) {
        try{
            // 密钥信息从环境变量读取，需要提前在环境变量中设置 TENCENTCLOUD_SECRET_ID 和 TENCENTCLOUD_SECRET_KEY
            // 使用环境变量方式可以避免密钥硬编码在代码中，提高安全性
            // 生产环境建议使用更安全的密钥管理方案，如密钥管理系统(KMS)、容器密钥注入等
            // 请参见：https://cloud.tencent.com/document/product/1278/85305
            // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
            Credential cred = new Credential(TENCENTCLOUD_SECRET_ID, TENCENTCLOUD_SECRET_KEY);
            // 使用临时密钥示例
            // Credential cred = new Credential("SecretId", "SecretKey", "Token");
            // 实例化一个http选项，可选的，没有特殊需求可以跳过
            HttpProfile httpProfile = new HttpProfile();
            httpProfile.setEndpoint("sms.tencentcloudapi.com");
            // 实例化一个client选项，可选的，没有特殊需求可以跳过
            ClientProfile clientProfile = new ClientProfile();
            clientProfile.setHttpProfile(httpProfile);
            // 实例化要请求产品的client对象,clientProfile是可选的
            SmsClient client = new SmsClient(cred, "ap-nanjing", clientProfile);
            // 实例化一个请求对象,每个接口都会对应一个request对象
            SendSmsRequest req = new SendSmsRequest();
            /*
                下发手机号码，采用 E.164 标准，格式为+[国家或地区码][手机号]，单次请求最多支持200个手机号且要求全为境内手机号或全为境外手机号。
                例如：+8618501234444， 其中前面有一个+号 ，86为国家码，18501234444为手机号。
                注：发送国内短信格式还支持0086、86或无任何国家或地区码的11位手机号码，前缀默认为+86。

                示例值
                ["+8618501234444"]
             */
//            String[] phoneNumberSet1 = {"13151291333"};
            req.setPhoneNumberSet(phoneNumberSet1);

            /*
            短信 SdkAppId，在 短信控制台  添加应用后生成的实际 SdkAppId，示例如1400006666。

            示例值
            1400006666
             */
            req.setSmsSdkAppId(SDK_APP_ID);
            /*
            模板 ID，必须填写已审核通过的模板 ID。模板 ID 可前往 国内短信 或 国际/港澳台短信 的正文模板管理查看，若向境外手机号发送短信，仅支持使用国际/港澳台短信模板。

            示例值
            1110
             */
            req.setTemplateId(sendSmsEnum.getTemplateId());
            /*
            短信签名内容，使用 UTF-8 编码，必须填写已审核通过的签名，例如：腾讯云，签名信息可前往 国内短信 或 国际/港澳台短信 的签名管理查看。

            发送国内短信该参数必填，且需填写签名内容而非签名ID。
            发送国际/港澳台短信该参数非必填。
            示例值
            腾讯云
             */
            req.setSignName(sendSmsEnum.getSignName());

            /*
            模板参数，若无模板参数，则设置为空。
            模板参数的个数需要与 TemplateId 对应模板的变量个数保持一致。

            示例值
            ["4370"]
             */
//            if (SendSmsEnum.VERIFICATION_CODE_LOGIN.compareTo(sendSmsEnum) == 0) {
//                String[] templateParamSet1 = {"tempParams"};
//                req.setTemplateParamSet(templateParamSet1);
            String[] templateParamSet = sendSmsEnum.getTemplateParamSet();
            log.info("验证码为：{}", templateParamSet[0]);
            req.setTemplateParamSet(templateParamSet);
//            }

            /*
            短信码号扩展号，默认未开通，如需开通请联系 腾讯云短信小助手。

            示例值
            10
             */
//            req.setExtendCode("extCode");
            /*
            用户的 session 内容，可以携带用户侧 ID 等上下文信息，server 会原样返回。注意长度需小于512字节。

            示例值
            outsid_1729495320_1011
             */
//            req.setSessionContext("sessCont");
            /*
            国内短信无需填写该项；国际/港澳台短信已申请独立 SenderId 需要填写该字段，默认使用公共 SenderId，无需填写该字段。
            注：月度使用量达到指定量级可申请独立 SenderId 使用，详情请联系 腾讯云短信小助手。

            示例值
            Qsms
             */
//            req.setSenderId("sendId");
            // 返回的resp是一个SendSmsResponse的实例，与请求对象对应
            SendSmsResponse resp = client.SendSms(req);
            // 输出json格式的字符串回包
            /*
                {
                    "SendStatusSet": [
                        {
                            "SerialNo": "4413:415301631717600741496829133",
                            "PhoneNumber": "+8613151291333",
                            "Fee": 1,
                            "SessionContext": "",
                            "Code": "Ok",
                            "Message": "send success",
                            "IsoCode": "CN"
                        }
                    ],
                    "RequestId": "a4d1424d-061f-4481-aae8-9683aaf2780d"
                }
             */
//            System.out.println(AbstractModel.toJsonString(resp));
            String jsonString = AbstractModel.toJsonString(resp);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            JSONArray sendStatusSet = jsonObject.getJSONArray("SendStatusSet");
            if (!sendStatusSet.isEmpty()) {
                JSONObject jsonObject1 = sendStatusSet.getJSONObject(0);
                String code = jsonObject1.getString("Code");
                if (!"Ok".equals(code)) {
                    log.error("短信发送失败,返回信息提示未成功！{}", jsonString);
                    throw new RuntimeException("短信发送失败！");
                } else {
                    return;
                }
            }
            log.error("短信发送失败,未解析到接口返回信息！{}", jsonString);
            throw new RuntimeException("短信发送失败！");

        } catch (TencentCloudSDKException e) {
//            System.out.println(e.toString());
            log.error(e.toString());
            throw new RuntimeException("短信发送失败！");
        }
    }

    public static void main(String[] args) {
        sendSms(SendSmsEnum.VERIFICATION_CODE_LOGIN, "13151291333");


//        String jsonString = "{\n" +
//                "                    \"SendStatusSet\": [\n" +
//                "                        {\n" +
//                "                            \"SerialNo\": \"4413:415301631717600741496829133\",\n" +
//                "                            \"PhoneNumber\": \"+8613151291333\",\n" +
//                "                            \"Fee\": 1,\n" +
//                "                            \"SessionContext\": \"\",\n" +
//                "                            \"Code\": \"Ok\",\n" +
//                "                            \"Message\": \"send success\",\n" +
//                "                            \"IsoCode\": \"CN\"\n" +
//                "                        }\n" +
//                "                    ],\n" +
//                "                    \"RequestId\": \"a4d1424d-061f-4481-aae8-9683aaf2780d\"\n" +
//                "                }";
//
//        JSONObject jsonObject = JSON.parseObject(jsonString);
//        JSONArray sendStatusSet = jsonObject.getJSONArray("SendStatusSet");
//        if (!sendStatusSet.isEmpty()) {
//            JSONObject jsonObject1 = sendStatusSet.getJSONObject(0);
//            String code = jsonObject1.getString("Code");
//            if (!"Ok".equals(code)) {
//                log.error("短信发送失败,返回信息提示未成功！{}", jsonString);
//                throw new RuntimeException("短信发送失败！");
//            } else {
//                return;
//            }
//        }
//        log.error("短信发送失败,未解析到接口返回信息！{}", jsonString);
    }
}